/**
 * 文件名：****.java.
 * 版权：Copyright Lightkit All Rights Reserved.
 * 描述：text.
 */
package com.lightkits.wms.domain.orderscanner.impl;

import com.lightkits.common.TransactionValidate;
import com.lightkits.common.db.entity.BdTag;
import com.lightkits.common.db.entity.WmExecuteLine;
import com.lightkits.common.db.entity.WmSaleTicketLine;
import com.lightkits.common.db.entity.WmSalesTicket;
import com.lightkits.common.db.entity.event.BdEvent;
import com.lightkits.common.db.entity.event.BdEventRecord;
import com.lightkits.framework.common.exception.LightKitsBizException;
import com.lightkits.framework.common.logging.Logger;
import com.lightkits.framework.common.logging.LoggerFactory;
import com.lightkits.framework.common.model.CheckResult;
import com.lightkits.framework.common.model.IResult;
import com.lightkits.framework.common.utility.json.JsonUtil;
import com.lightkits.framework.common.utility.object.ObjectUtil;
import com.lightkits.framework.common.utility.validate.IntegrityValidator;
import com.lightkits.wms.domain.orderscanner.CreateDocScanParams;
import com.lightkits.wms.domain.orderscanner.CreateTagAndSubParams;
import com.lightkits.wms.domain.orderscanner.UseOrdScaParams;
import com.lightkits.wms.domain.rawmatstorage.repo.WmExecuteLineService;
import com.lightkits.wms.domain.saleticket.repo.WmSaleTicketLineService;
import com.lightkits.wms.domain.saleticket.repo.WmSaleTicketService;
import com.lightkits.wms.domain.saveonhand.repo.BdEventRecordService;
import com.lightkits.wms.domain.saveonhand.repo.BdEventService;
import com.lightkits.wms.domain.stocktransfer.service.SubStockTransferDomain;
import com.lightkits.wms.domain.tagservice.UseTagParamsService;
import com.lightkits.wms.dto.orderscanner.model.ScannerHeaderDto;
import com.lightkits.wms.dto.orderscanner.model.ScannerLineDto;
import com.lightkits.wms.dto.stocktransfer.model.SubStockViewDTO;
import com.lightkits.wms.dto.tagservice.model.TagViewDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author jing.wei@hand-china.com
 * @date 2019/6/20 16:20
 **/
@Service
public class UseOrdScaParamsImpl implements UseOrdScaParams {
    private final static Logger LOGGER = LoggerFactory.getLogger(UseOrdScaParamsImpl.class);
    private final BdEventService bdEventService;
    private final BdEventRecordService bdEventRecordService;
    private final WmSaleTicketService wmSaleTicketService;
    private final WmSaleTicketLineService wmSaleTicketLineService;
    private final UseTagParamsService useTagParamsService;
    private final SubStockTransferDomain subStockTransferDomain;
    private final CreateDocScanParams createDocScanParams;
    private final CreateTagAndSubParams createTagAndSubParams;
    private final CreateScaEventParamsImpl createScaEventParams;

    @Autowired
    public UseOrdScaParamsImpl(BdEventService bdEventService, BdEventRecordService bdEventRecordService, WmSaleTicketService wmSaleTicketService, WmSaleTicketLineService wmSaleTicketLineService, UseTagParamsService useTagParamsService, SubStockTransferDomain subStockTransferDomain, CreateDocScanParams createDocScanParams, CreateTagAndSubParams createTagAndSubParams, CreateScaEventParamsImpl createScaEventParams, WmExecuteLineService wmExecuteLineService) {
        this.bdEventService = bdEventService;
        this.bdEventRecordService = bdEventRecordService;
        this.wmSaleTicketService = wmSaleTicketService;
        this.wmSaleTicketLineService = wmSaleTicketLineService;
        this.useTagParamsService = useTagParamsService;
        this.subStockTransferDomain = subStockTransferDomain;
        this.createDocScanParams = createDocScanParams;
        this.createTagAndSubParams = createTagAndSubParams;
        this.createScaEventParams = createScaEventParams;
        this.wmExecuteLineService = wmExecuteLineService;
    }

    private final WmExecuteLineService wmExecuteLineService;

    private IResult checkParams(ScannerHeaderDto headerDto, List<ScannerLineDto> lineDtos) {
        try {
            //售货单头信息必输校验
            IntegrityValidator.begin().validate(headerDto.getOrgId(), "Organization Id")
                    .validate(headerDto.getDelieveyWays(), "Deleivery Ways")
                    .validate(headerDto.getBookMoney(), "Book Money")
                    .validate(headerDto.getGoodTotal(), "Goods Total");
            //数字格式的校验
            Pattern pattern = Pattern.compile("([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])");
            if (!pattern.matcher(headerDto.getGoodTotal()).matches()) {
                return IResult.fail("The Goods Total is invalid");
            }

            Pattern pattern1 = Pattern.compile("^[0-9]{1,4}+(\\.[0-9]{1,6})?$");
            if (!ObjectUtil.isNullOrEmpty(headerDto.getFreight())
                    && !pattern1.matcher(headerDto.getFreight()).matches()) {
                return IResult.fail("The Frieght is invalid");
            }
            if (!ObjectUtil.isNullOrEmpty(headerDto.getPriceTotal())
                    && !pattern.matcher(headerDto.getPriceTotal()).matches()) {
                return IResult.fail("The Price Total is invalid");
            }
            if (!ObjectUtil.isNullOrEmpty(headerDto.getBookMoney())
                    && !pattern.matcher(headerDto.getBookMoney()).matches()) {
                return IResult.fail("The Booked Money is invalid");
            }
            //售货单行的必输参数校验
            lineDtos.forEach(line -> {
                IntegrityValidator.begin().validate(line.getItemId(), "Item Id")
                        .validate(line.getTagId(), "Tag Id")
                        .validate(line.getWarehouseId(), "Warehosue Id")
                        .validate(line.getToWarehouseId(), "To Warehouse Id")
                ;
                //售货单行的参数有效性校验
                TransactionValidate check1 = TransactionValidate
                        .beginValidity(BdTag.class);
                check1.checkIdValidity(
                        ObjectUtil.toString(line.getTagId()),
                        "ID");

            });
        } catch (LightKitsBizException e) {
            return e.result();
        }
        return IResult.success();
    }

    /**
     * 创建扫描订单数据
     *
     * @param headerDto 扫描订单头
     * @param lineDtos  扫描订单行
     * @return IResult
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public IResult scannerValue(ScannerHeaderDto headerDto, List<ScannerLineDto> lineDtos) {
        try {
            //参数检查
            IResult result = checkParams(headerDto, lineDtos);
            if (!result.isSuccessful()) {
                return result;
            }
            //创建事件
            CheckResult checkResult = createScaEventParams.createEvent(headerDto, "WM_SALE_ORDER");
            if (!checkResult.isSuccessful() || checkResult.getData() == null) {
                throw new LightKitsBizException(checkResult.getMessage());
            }
            BdEvent event = (BdEvent) checkResult.getData();
            boolean eventFlag = bdEventService.insert(event);
            if (!eventFlag) {
                throw new LightKitsBizException("Insert Event Error");
            }
            //创建售货单头
            checkResult = createDocScanParams.createSaleHead(headerDto);
            if (!checkResult.isSuccessful() || checkResult.getData() == null) {
                throw new LightKitsBizException(checkResult.getMessage());
            }
            WmSalesTicket header = (WmSalesTicket) checkResult.getData();
            boolean headrFlag = wmSaleTicketService.insert(header);
            if (!headrFlag) {
                throw new LightKitsBizException("Insert Sale Ticket Error");
            }
            List<BdEventRecord> records = new ArrayList<>();
            //创建快照
            checkResult = createScaEventParams.createEventRecord("SALE_ORDER_HADER", "",
                    header.getId(), "", JsonUtil.toString(header));

            if (!checkResult.isSuccessful() || checkResult.getData() == null) {
                throw new LightKitsBizException(checkResult.getMessage());
            }
            BdEventRecord bdEventRecord = (BdEventRecord) checkResult.getData();
            bdEventRecord.setEventId(event.getId());
            records.add(bdEventRecord);
            //创建售货单行
            checkResult = createDocScanParams.createSaleLine(lineDtos, header.getId(), header.getCurrency());
            if (!checkResult.isSuccessful() || checkResult.getData() == null) {
                throw new LightKitsBizException(checkResult.getMessage());
            }
            List<WmSaleTicketLine> lines = (List<WmSaleTicketLine>) checkResult.getData();
            boolean linesFlag = wmSaleTicketLineService.insertBatch(lines);
            if (!linesFlag) {
                throw new LightKitsBizException("Insert Sale Ticket Line Error");
            }
            //创建售货单行快照
            lines.forEach(target -> {
                CheckResult<BdEventRecord> checkResult1 = createScaEventParams.createEventRecord(
                        "SALE_ORDER_LINE", target.getTagId().toString(), target.getId(),
                        "", JsonUtil.toString(target)
                );
                if (!checkResult1.isSuccessful() || checkResult1.getData() == null) {
                    throw new LightKitsBizException(checkResult1.getMessage());
                }
                BdEventRecord eventRecord = checkResult1.getData();
                eventRecord.setEventId(event.getId());
                records.add(eventRecord);

            });
            //创建售货单行执行
            checkResult = createDocScanParams.createExeLine(lineDtos, lines, header.getId(), event.getId());
            if (!checkResult.isSuccessful() || checkResult.getData() == null) {
                throw new LightKitsBizException(checkResult.getMessage());
            }
            List<WmExecuteLine> exeLines = (List<WmExecuteLine>) checkResult.getData();
            boolean linesExeFlag = wmExecuteLineService.insertBatch(exeLines);
            if (!linesExeFlag) {
                throw new LightKitsBizException("Insert Execute Line Line Error");
            }
            //创建条码参数
            checkResult = createTagAndSubParams.createTags(lineDtos, event, lines, headerDto.getOrgId());
            if (!checkResult.isSuccessful() || checkResult.getData() == null) {
                throw new LightKitsBizException(checkResult.getMessage());
            }
            List<TagViewDto> tagViewDtos = (List<TagViewDto>) checkResult.getData();

            result = useTagParamsService.insertValue(tagViewDtos);
            if (!result.isSuccessful()) {
                throw new LightKitsBizException(result.getMessage());
            }

            //创建子库存转移参数
            checkResult = createTagAndSubParams.createSubStockParam(headerDto, lineDtos);
            if (!checkResult.isSuccessful() || checkResult.getData() == null) {
                throw new LightKitsBizException(checkResult.getMessage());
            }
            List<SubStockViewDTO> subStockViewDTOS = (List<SubStockViewDTO>) checkResult.getData();
            subStockViewDTOS.forEach(sub -> {
                sub.setParentEventId(event.getId().toString());
                IResult result1 = subStockTransferDomain.subStockTransfer(sub);
                if (!result1.isSuccessful()) {
                    throw new LightKitsBizException(result1.getMessage());
                }
            });
            //插入快照
            boolean recordsFlag = bdEventRecordService.insertBatch(records);
            if (!recordsFlag) {
                throw new LightKitsBizException("Insert Records Error");
            }


        } catch (Exception e) {
            LOGGER.error("create Scanner Order .error", e);
        }
        return IResult.success();

    }

}
